/**
 * Source file for the {@link fr.prolavage.domain.beans.Entite} type.
 * 
 * This source file belongs to a software project managed by the
 * Prolavage SARL company located in FRANCE.
 * Prolavage operates a truck washing station.
 *
 * This software project helps Prolavage manages its enterprise resources.
 * The main features consists in printing a ticket for each customer
 * with the details of the vehicle washing service to be provided.
 *
 * Copyright (C) 2014 Prolavage SARL
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * This software project MUST comply with the law of FRANCE, and with
 * the law and regulations of the European Union.
 * Since this software project is provided without any warranty,
 * it MAY NOT comply with the law of any other country.
 *
 * This source file MAY contain text written in the english and/or french languages.
 * For legal considerations, the french language SHOULD take precedence.
 *
 * This software project is hosted on https://code.google.com/p/prolavage/
 * Do not hesitate to visit our blog as well: http://prolavage.fr
 *
 * We can be contacted by postmail using the following address:
 *
 * Pro Lavage Poids Lourds SARL
 * ZI du Cormier – Bd du Cormier
 * 49300 CHOLET
 * FRANCE
 *
 */

package fr.prolavage.domain.beans;

import java.io.IOException;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.Set;

import org.apache.commons.io.IOUtils;

import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.gson.stream.JsonWriter;

/**
 * Classe racine pour les entites qui utilisent la stategie de correspondance<br />
 * basee sur une table de base de donnee par classe concrete.
 * 
 * @author Adrien COLOM
 * 
 */
public class Entite implements Serializable {

   private static final String JSON_ID = "id";

   private static final String JSON_TYPE = "type";

   private static final long serialVersionUID = -5020644065559403110L;

   /**
    * Convertit l'ensemble d'entites en un ensemble d'identifiants.
    * 
    * @param entites
    *           Un ensemble d'entites.
    * @return L'ensemble des identifiants presents. Le resultat est toujours non-null.
    */
   public static Set<Integer> toSetOfIds(final Iterable<? extends Entite> entites) {

      if ((null == entites) || Iterables.isEmpty(entites)) {
         return ImmutableSet.of();
      }

      final Set<Integer> builder = Sets.newHashSetWithExpectedSize(Iterables.size(entites));

      for (final Entite e : Iterables.filter(entites, Predicates.notNull())) {
         final Integer eid = e.getId();
         if (null != eid) {
            builder.add(eid);
         }
      }

      return ImmutableSet.copyOf(builder);
   }

   private Integer id;

   /**
    * Constructeur pour empecher l'instantiation par defaut.
    */
   protected Entite() {

   }

   /**
    * @see java.lang.Object#equals(java.lang.Object)
    */
   @Override
   public boolean equals(final Object obj) {

      if (!(obj instanceof Entite)) {
         return false;
      }

      final Entite autre = (Entite) obj;

      if ((null == id) || (null == autre.id)) {
         return true;
      }

      return id.equals(autre.id);
   }

   /**
    * Getter.
    * 
    * @return l'identifiant de base de donnee.
    */
   public Integer getId() {

      return id;
   }

   /**
    * @see java.lang.Object#hashCode()
    */
   @Override
   public int hashCode() {

      return Integer.MAX_VALUE;
   }

   protected void serializeToJSON(final JsonWriter jsonWriter) throws IOException {

      jsonWriter.name(JSON_TYPE);
      jsonWriter.value(getClass().getSimpleName());

      jsonWriter.name(JSON_ID);
      jsonWriter.value(id);
   }

   /**
    * Setter.
    * 
    * @param id
    *           l'id.
    */
   public void setId(final Integer id) {

      this.id = id;
   }

   /**
    * @see java.lang.Object#toString()
    */
   @Override
   public String toString() {

      String str = null;

      final StringWriter sw = new StringWriter();
      final JsonWriter json = new JsonWriter(sw);

      try {
         json.beginObject();
         serializeToJSON(json);
         json.endObject();
         json.close();
         str = sw.toString();
      } catch (final IOException io) {
         throw new IllegalStateException(io);
      } finally {
         IOUtils.closeQuietly(sw);
      }

      return str;
   }

}
